#ifndef __VIMOCK_OBJECT__
#define __VIMOCK_OBJECT__

#include <vector>
#include <memory>
#include "object_holder.hpp"

namespace vimock {
class object {
public:
	template <typename ValueType>
	object(const ValueType & value) :
		holder(new default_object_holder<ValueType>(value)) {
	}
	object(const object & that) :
		holder(that.holder) {
	}
	bool equals(object thatObj) const {
		return holder->equals(thatObj);
	}
	template <typename ToType>
	ToType to() const {
		return holder->to<ToType>();
	}
private:
	object_holder holder;
	template <typename ValueType>
	class default_object_holder : public _object_holder {
	public:
		default_object_holder(const ValueType & value) :
			value(value) {
		}
		virtual bool equals(object thatObj) const {
			try {
				ValueType that(thatObj.to<ValueType>());
				return that == value;
			}
			catch (const bad_object_cast &)
			{
				return false;
			}
		}
	protected:
		virtual const std::type_info & get_type() const {
			return typeid(ValueType);
		}
		virtual const void * const get_value() const {
			return &value;
		}
	private:
		ValueType value;
	};
};
typedef std::tr1::shared_ptr<std::vector<object> > object_vector;
}

#endif //__VIMOCK_OBJECT__ 
